#include "PreCompiledHeader.h"
#include "GameState_Asteroid.hpp"
#include "System.hpp"
#include "Renderer.hpp"
#include "Collision.h"
#include "Vector2D.h"
#include "Timer.h"
#include <string>
#include <sstream>
/******************************************************************************/
/*!
	Defines
*/
/******************************************************************************/
const float PI =  float(3.1415926535897932384626433832795);

const unsigned int	GAME_OBJ_NUM_MAX		= 32;			//The total number of different objects (Shapes)
const unsigned int	GAME_OBJ_INST_NUM_MAX	= 2048;			//The total number of different game object instances

const unsigned int	SHIP_INITIAL_NUM		= 3;			// initial number of ship lives
const float			SHIP_SIZE				= 30.0f;			// ship size

const float			SHIP_MAX_SPEED			    = 50.0f;		// Maximum speed (m/s)
const Vector2D      BOUNDING_RECT_SIZE      ( 1.0f, 1.0f ); //Size of the bounding rectangle


const float			SHIP_ACCEL_FORWARD		= 40.0f;		// ship forward acceleration (in m/s^2)
const float			SHIP_ACCEL_BACKWARD		= -40.0f;		// ship backward acceleration (in m/s^2)
const float			SHIP_ROT_SPEED			= (3.0f * PI);	// ship rotation speed (degree/second)


const float			BULLET_SPEED			= 80.0f;		// bullet speed (m/s)
const float	        BULLET_SIZE             = 10.0f;			//Size of the bullet      
const int           MAX_ASTEROID_ONSCREEN   = 8;            // Maximum number of Aestroid onscreen  


#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

//if(KEY_DOWN(VK_LEFT))
//{
//
//
//}

double S_bulletTime;

// -----------------------------------------------------------------------------
enum TYPE
{
	// list of game object types
	
	TYPE_SHIP = 0, 
	TYPE_ASTEROID,
	TYPE_BULLET,
	TYPE_BACKGROUND
};


// -----------------------------------------------------------------------------
// object flag definition
const unsigned long FLAG_ACTIVE				= 0x00000001;

/******************************************************************************/
/*!
	Struct/Class Definitions
*/
/******************************************************************************/

//Game object structure
struct GameObj
{
	unsigned long		type;		// object type
	
};

// ---------------------------------------------------------------------------

//Game object instance structure
struct GameObjInst
{
	GameObj*			pObject;	// pointer to the 'original' shape
	unsigned long		flag;		// bit flag or-ed together
	float				scale;		// scaling value of the object instance
	Vec2				posCurr;	// object current position
	Vec2				velCurr;	// object current velocity
	float				dirCurr;	// object current direction
	AABB				boundingBox;// object bouding box that encapsulates the object
	D3DXMATRIX			transform;	// object transformation matrix: Each frame, 
	// calculate the object instance's transformation matrix and save it here

	//void				(*pfUpdate)(void);
	//void				(*pfDraw)(void);
};

static float fRand(float start, float end);

/******************************************************************************/
/*!
	Static Variables
*/
/******************************************************************************/

// list of original object
static GameObj				sGameObjList[GAME_OBJ_NUM_MAX];				// Each element in this array represents a unique game object (shape)
static unsigned long		sGameObjNum;								// The number of defined game objects

// list of object instances
static GameObjInst			sGameObjInstList[GAME_OBJ_INST_NUM_MAX];	// Each element in this array represents a unique game object instance (sprite)
static unsigned long		sGameObjInstNum;							// The number of used game object instances

// pointer ot the ship object
static GameObjInst*			spShip;										// Pointer to the "Ship" game object instance

// number of ship available (lives 0 = game over)
static long					sShipLives;									// The number of lives left

// the score = number of asteroid destroyed
static unsigned long		sScore;										// Current score

// Flag of the the aestroid. True if there is none. 
static bool NoAsteroid= true; 

//Spawnpoint of the Aestroid
static Vector2D				SpawnPoints[8]; 

// ---------------------------------------------------------------------------

// functions to create/destroy a game object instance
static GameObjInst*			gameObjInstCreate (unsigned long type, float scale, 
											   Vec2* pPos, Vec2* pVel, float dir);
static void					gameObjInstDestroy(GameObjInst* pInst);

/******************************************************************************/
/*!
	"Load" function of this state
*/
/******************************************************************************/
void SinglePlayerAsteroidsLoad(void)
{
	// zero the game object array
	memset(sGameObjList, 0, sizeof(GameObj) * GAME_OBJ_NUM_MAX);
	// No game objects (shapes) at this point
	sGameObjNum = 0;

	// zero the game object instance array
	memset(sGameObjInstList, 0, sizeof(GameObjInst) * GAME_OBJ_INST_NUM_MAX);

	// No game object instances (sprites) at this point
	sGameObjInstNum = 0;

	// The ship object instance hasn't been created yet, so this "spShip" pointer is initialized to 0
	spShip = 0;

	// load/create the mesh data (game objects / Shapes)
	GameObj* pObj;

	// =====================
	// create the ship 
	// =====================
	pObj		= sGameObjList + sGameObjNum++;
	pObj->type	= TYPE_SHIP;

	
	// =========================
	// create the asteroid 
	// =========================
	pObj		= sGameObjList + sGameObjNum++;
	pObj->type	= TYPE_ASTEROID;

	// =======================
	// create the bullet 
	// =======================
	pObj		= sGameObjList + sGameObjNum++;
	pObj->type	= TYPE_BULLET;

	//create the background
	pObj		= sGameObjList + sGameObjNum++;
	pObj->type	= TYPE_BACKGROUND;

}

/******************************************************************************/
/*!
	"Initialize" function of this state
*/
/******************************************************************************/
void SinglePlayerAsteroidsInit(void)
{

		Vec2 pos, vel;
	// create the main ship
	spShip = gameObjInstCreate(TYPE_SHIP, SHIP_SIZE, 0, 0, 0.0f);


	// CREATE THE INITIAL ASTEROIDS INSATNCES USING THE "GAMEOBJINSTCREATE" FUNCTION
	//4 initial asteroids instances with defined positions and velocities.
	GameObjInst* pInst = &sGameObjInstList[1];
	pos.x = static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	pos.y = static_cast<float>(SYSTEM->GetWindowHeight()/2);
	
	vel.x = 40.0f;	vel.y = 20.0f;
	pInst = gameObjInstCreate(TYPE_ASTEROID, 30.0f, &pos, &vel, 0.0f);

	pInst = &sGameObjInstList[2];
	pos.x = static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	pos.y = static_cast<float>(SYSTEM->GetWindowHeight()/2);
	vel.x = -30.0f;	vel.y = 10.0f;
	pInst = gameObjInstCreate(TYPE_ASTEROID, 25.0f, &pos, &vel, 0.0f);

	pInst = &sGameObjInstList[3];
	pos.x = static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	pos.y = static_cast<float>(SYSTEM->GetWindowHeight()/2);
	vel.x = 15.0f;	vel.y = -15.0f;
	pInst = gameObjInstCreate(TYPE_ASTEROID, 30.0f, &pos, &vel, 0.0f);

	pInst = &sGameObjInstList[4];
	pos.x = static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	pos.y = static_cast<float>(SYSTEM->GetWindowHeight()/2);
	vel.x = -8.0f;	vel.y = -12.0f;
	pInst = gameObjInstCreate(TYPE_ASTEROID, 25.0f, &pos, &vel, 0.0f);


	pInst = &sGameObjInstList[5];
	pos.x = static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	pos.y = static_cast<float>(SYSTEM->GetWindowHeight()/2);
	vel.x = -6.0f;	vel.y = -15.0f;
	pInst = gameObjInstCreate(TYPE_ASTEROID, 25.0f, &pos, &vel, 0.0f);

	pInst = &sGameObjInstList[6];
	pos.x = static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	pos.y = static_cast<float>(SYSTEM->GetWindowHeight()/2);
	vel.x = -12.0f;	vel.y = -10.0f;
	pInst = gameObjInstCreate(TYPE_ASTEROID, 25.0f, &pos, &vel, 0.0f);

		pInst = &sGameObjInstList[7];
	pos.x = static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	pos.y = static_cast<float>(SYSTEM->GetWindowHeight()/2);
	vel.x = -12.0f;	vel.y = -10.0f;
	pInst = gameObjInstCreate(TYPE_ASTEROID, 25.0f, &pos, &vel, 0.0f);

	
	
	
	//back ground as a object.
	pInst = &sGameObjInstList[5];
	pInst = gameObjInstCreate(TYPE_BACKGROUND, 900, 0, 0, 0.0f);
	
	// reset the score and the number of ship
	sScore      = 0;
	sShipLives  = SHIP_INITIAL_NUM;

	SpawnPoints[0].x= static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	SpawnPoints[0].y= static_cast<float>(SYSTEM->GetWindowHeight()/2 + SHIP_SIZE/3);
	
	SpawnPoints[1].x= static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	SpawnPoints[1].y= -static_cast<float>(SYSTEM->GetWindowHeight()/2 - SHIP_SIZE/3);
	
	SpawnPoints[2].x= static_cast<float>(SYSTEM->GetWindowWidth()/2 + SHIP_SIZE/3);
	SpawnPoints[2].y= static_cast<float>(rand() % SYSTEM->GetWindowHeight()/2 - SYSTEM->GetWindowHeight()/2);

	SpawnPoints[3].x= -static_cast<float>(SYSTEM->GetWindowWidth()/2 - SHIP_SIZE/3);
	SpawnPoints[3].y= static_cast<float>(rand() % SYSTEM->GetWindowHeight()/2 - SYSTEM->GetWindowHeight()/2);


	SpawnPoints[4].x= static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	SpawnPoints[4].y= static_cast<float>(SYSTEM->GetWindowHeight()/2 + SHIP_SIZE/3);
	
	SpawnPoints[5].x= static_cast<float>(rand() % SYSTEM->GetWindowWidth() - SYSTEM->GetWindowWidth()/2); 
	SpawnPoints[5].y= -static_cast<float>(SYSTEM->GetWindowHeight()/2 - SHIP_SIZE/3);
	
	SpawnPoints[6].x= static_cast<float>(SYSTEM->GetWindowWidth()/2 + SHIP_SIZE/3);
	SpawnPoints[6].y= static_cast<float>(rand() % SYSTEM->GetWindowHeight()/2 - SYSTEM->GetWindowHeight()/2);

	SpawnPoints[7].x= -static_cast<float>(SYSTEM->GetWindowWidth()/2 - SHIP_SIZE/3);
	SpawnPoints[7].y= static_cast<float>(rand() % SYSTEM->GetWindowHeight()/2 - SYSTEM->GetWindowHeight()/2);
}

/******************************************************************************/
/*!
	"Update" function of this state
*/
/******************************************************************************/
void SinglePlayerAsteroidsUpdate(void)
{
	
	float AccelerateDeccelerate = 0.0f;
	spShip->velCurr.x = 0;
	spShip->velCurr.y = 0;
	
	// ======================================================
	// update and limit the Velocity of the Ship 
	// ======================================================
	//Velocity of the ship according to the acceleration.
	Vec2 added(cosf(spShip->dirCurr), sinf(spShip->dirCurr));
	
	if (KEY_DOWN(0x52) && sShipLives <= 0)
	{
		gGameStateNext = GS_RESTART; 
	}

	if (KEY_DOWN(VK_ESCAPE))
	{
		gGameStateNext = GS_MAINMENU; 
	}

	if (KEY_DOWN(VK_UP))
	{
		spShip->velCurr += ( SHIP_MAX_SPEED * added);
		//get the normal direction.
		float y = spShip->velCurr.x; 
		spShip->velCurr.x =  -spShip->velCurr.y; 
		spShip->velCurr.y = y;
	}


	if (KEY_DOWN(VK_LEFT))
	{
		spShip->dirCurr += SHIP_ROT_SPEED * (float)(Timer::GetInstance()->GetDeltaTime());
	//	std::cout << Timer::GetInstance()->GetDeltaTime() << std::endl;
	}

	if (KEY_DOWN(VK_RIGHT))
	{
		spShip->dirCurr -= SHIP_ROT_SPEED * (float)(Timer::GetInstance()->GetDeltaTime());
	}

	// Shoot a bullet if space is triggered (Create a new object instance)
	S_bulletTime +=  Timer::GetInstance()->GetDeltaTime();
	
	if (KEY_DOWN(VK_SPACE) && (S_bulletTime) > 0.1f )
	{	
		S_bulletTime = 0;

		float bullDir=0.0f;
		Vector2D  bullVel, bullPos;
		GameObjInst* pInst;

		// Get the bullet's direction according to the ship's direction
		bullDir = spShip->dirCurr;
		
		// Set the velocity
		bullVel.x = (cosf(bullDir+ 2.0f*3.14f/180.0f) * BULLET_SPEED);
		bullVel.y = (sinf(bullDir+ 2.0f*3.14f/180.0f) * BULLET_SPEED);

		float y	  = bullVel.y;
		bullVel.y = bullVel.x;
		bullVel.x = -y;

		//Set the position in front of the ship
		bullPos.x = spShip->posCurr.x-BOUNDING_RECT_SIZE.x*0.5f;
		bullPos.y = spShip->posCurr.y;

		// Create an instance of bullet
		pInst = gameObjInstCreate(TYPE_BULLET, BULLET_SIZE, &bullPos,
		&bullVel, bullDir);		
	}

	// ======================================================
	// update physics of all active game object instances
	//	-- Positions are updated here with the computed velocity
	//  -- Get the bouding rectangle of every active instance:
	//		boundingRect_min = -BOUNDING_RECT_SIZE * instance->scale + instance->pos
	//		boundingRect_max = BOUNDING_RECT_SIZE * instance->scale + instance->pos
	// ======================================================
	for (unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = &sGameObjInstList[i];
		// skip non-active object
		if ((pInst->flag & FLAG_ACTIVE) == 0)
		{
			continue;
		}
		//Update Ship's position
		pInst->posCurr += 5 * pInst->velCurr * (float)(Timer::GetInstance()->GetDeltaTime());
		spShip->velCurr.x = 0;
		spShip->velCurr.y = 0;
				
		//Bouding Box of every active instance
		pInst->boundingBox.min= pInst->posCurr - (BOUNDING_RECT_SIZE * pInst->scale * 0.5f);
		pInst->boundingBox.max= pInst->posCurr + (BOUNDING_RECT_SIZE * pInst->scale * 0.5f);

	}

	for (unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = sGameObjInstList + i;

		// skip non-active object
		if ((pInst->flag & FLAG_ACTIVE) == 0)
			continue;
		
		if(pInst->pObject->type == TYPE_BULLET)
		{
			if(	pInst->posCurr.x < -SYSTEM->GetWindowWidth()/2 - SHIP_SIZE/2 ||
				pInst->posCurr.x > SYSTEM->GetWindowWidth()/2 + SHIP_SIZE/2 ||
				pInst->posCurr.y < -SYSTEM->GetWindowHeight()/2 - SHIP_SIZE/2 ||
				pInst->posCurr.y >  SYSTEM->GetWindowHeight()/2 +SHIP_SIZE/2 )
			{
				gameObjInstDestroy(pInst);
			}
		}
		else
		{
			if(pInst->posCurr.x > SYSTEM->GetWindowWidth()/2 + SHIP_SIZE/2)
			{
				pInst->posCurr.x = -float(SYSTEM->GetWindowWidth())/2;
			}
			else if(pInst->posCurr.x < -SYSTEM->GetWindowWidth()/2 - SHIP_SIZE/2)
			{
				pInst->posCurr.x = float(SYSTEM->GetWindowWidth())/2;
			}
			if(pInst->posCurr.y > SYSTEM->GetWindowHeight()/2 + SHIP_SIZE/2)
			{
				pInst->posCurr.y = -float(SYSTEM->GetWindowHeight())/2;
			}
			else if(pInst->posCurr.y < -SYSTEM->GetWindowHeight()/2 -SHIP_SIZE/2)
			{
				pInst->posCurr.y = float(SYSTEM->GetWindowHeight())/2;
			}
		
		}

	}
	

	// ======================================================
	// check for collision
	// ======================================================
	//For each object instance: oi1
	//	if oi1 is not active
	//		skip
	//
	//	if oi1 is an asteroid
	//		for each object instance oi2
	//			if(oi2 is not active or oi2 is an asteroid)
	//				skip
	//
	//			if(oi2 is the ship)
	//				Check for collision between ship and asteroids (Rectangle - Rectangle)
	//				Update game behavior accordingly
	//				Update "Object instances array"
	//			else
	//			if(oi2 is a bullet)
	//				Check for collision between ship and asteroids (Rectangle - Rectangle)
	//				Update game behavior accordingly
	//				Update "Object instances array"
	// ======================================================
	for (unsigned long counter = 0; counter < GAME_OBJ_INST_NUM_MAX; ++counter)
	{
		GameObjInst* pInst = sGameObjInstList + counter;
	
		// skip non-active object
		if ((pInst->flag & FLAG_ACTIVE) == 0)
		{
			continue;
		}
		
		if (pInst->pObject->type == TYPE_ASTEROID)
		{	
			for (unsigned long counter1 = 0; counter1 < GAME_OBJ_INST_NUM_MAX; counter1++)
			{
				GameObjInst* pInst1 = sGameObjInstList + counter1;
				if ((pInst1->flag & FLAG_ACTIVE) == 0 || pInst1->pObject->type == TYPE_ASTEROID  )
				{
					continue;
				}

				else if(pInst1->pObject->type == TYPE_SHIP)
				{
					//If SHIP and Aesteroid collide
					if( CollisionIntersection_RectRect(pInst->boundingBox, pInst->velCurr, 
										               pInst1->boundingBox, pInst1->velCurr) )
					{	
						--sShipLives;
						gameObjInstDestroy(pInst);
					}
				}

				else if(pInst1->pObject->type == TYPE_BULLET)
				{
					if( CollisionIntersection_RectRect(pInst->boundingBox, pInst->velCurr, 
										               pInst1->boundingBox, pInst1->velCurr) )
					{	
							++sScore;
							gameObjInstDestroy(pInst1);
							gameObjInstDestroy(pInst);
					}
				}
			}
		}
	}

	// =====================================
	// calculate the matrix for all objects
	// =====================================
	for (unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = sGameObjInstList + i;
		D3DXMATRIX		 trans, rot, scale;

		// skip non-active object
		if ((pInst->flag & FLAG_ACTIVE) == 0)
			continue;

		// Compute the scaling matrix
		D3DXMatrixScaling(&scale, pInst->scale, pInst->scale,1.0f);
		D3DXMatrixRotationZ(&rot,pInst->dirCurr );
		D3DXMatrixTranslation(&trans,pInst->posCurr.x,pInst->posCurr.y,1);

		if(pInst->pObject->type == TYPE_BACKGROUND)
			D3DXMatrixTranslation(&trans,pInst->posCurr.x,pInst->posCurr.y,2);
		
		// Concatenate the 3 matrix in the correct order in the object instance's "transform" matrix
		pInst->transform= scale * rot * trans ;
	}

	// ======================================================
	// update active game object instances
	// Example:
	//		-- Wrap specific object instances around the world (Needed for the assignment)
	//		-- Removing the bullets as they go out of bounds (Needed for the assignment)
	//		-- If you have a homing missile for example, compute its new orientation 
	//			(Homing missiles are not required for the Asteroids project)
	//		-- Update a particle effect (Not required for the Asteroids project)
	// ======================================================
	for (unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = sGameObjInstList + i;

		// skip non-active object
		if ((pInst->flag & FLAG_ACTIVE) == 0)
			continue;	
	}

	// ======================================================
	// update physics of all active game object instances
	//	-- Positions are updated here with the computed velocity
	//  -- Get the bouding rectangle of every active instance:
	//		boundingRect_min = -BOUNDING_RECT_SIZE * instance->scale + instance->pos
	//		boundingRect_max = BOUNDING_RECT_SIZE * instance->scale + instance->pos
	// ======================================================
	for (unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = &sGameObjInstList[i];
		// skip non-active object
		if ((pInst->flag & FLAG_ACTIVE) == 0)
		{
			continue;
		}
		//Update Ship's position
		pInst->posCurr += pInst->velCurr * (float)(Timer::GetInstance()->GetDeltaTime());

		//Bouding Box of every active instance
		pInst->boundingBox.min= pInst->posCurr - (BOUNDING_RECT_SIZE * pInst->scale * 0.5f);
		pInst->boundingBox.max= pInst->posCurr + (BOUNDING_RECT_SIZE * pInst->scale * 0.5f);
		
	}
	
	// =====================================
	// Spawn Asteroid
	// ====================================
	for (unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = sGameObjInstList + i;

		// skip non-active object
		if ((pInst->flag & FLAG_ACTIVE) == 0)
			continue;
		
		// check if the object is a ship
		if (pInst->pObject->type == TYPE_ASTEROID)
		{
			NoAsteroid =false; 
			break;
		}
		NoAsteroid=true;
	}

	if(NoAsteroid==true)
	{
		for (unsigned long i = 0; i < MAX_ASTEROID_ONSCREEN; i++)
		{
		Vec2 pos, vel;
		vel.x = fRand(0, 100)-50.0f;	vel.y = fRand(0, 80)-50.0f;
		


		gameObjInstCreate(TYPE_ASTEROID,  fRand(10, 30), &SpawnPoints[i], &vel, 0.0f);
		}
	}
}

static float fRand(float start, float end)
{
	float multiplier = end - start;
	return (((float (rand())/RAND_MAX) * multiplier) + start);
}

/******************************************************************************/
/*!
	Drawing of Aestroid onto buffer
*/
/******************************************************************************/
void SinglePlayerAsteroidsDraw(void)
{
	SYSTEM->GetRenderer()->PrepareToDraw();
	char strBuffer[1024];
	sprintf_s(strBuffer, "Lives: %d", sShipLives);


	if(sShipLives <= 0)
	{
		SYSTEM->GetRenderer()->PrintTextWorld( "You Have Lost The Game!", -100.f, 0.f, WHITE, 500, 10);
		SYSTEM->GetRenderer()->PrintTextWorld( "Press R to Restart!", -100.f, -20.f, WHITE, 500, 10);

		sShipLives = 0;
	}
	
	

	//Draw Text
	SYSTEM->GetRenderer()->PrintTextWorld( strBuffer, float(SYSTEM->GetWindowWidth())/2 - 100, 
										float(SYSTEM->GetWindowHeight())/2 -10, WHITE, 100, 10);
	

	memset(strBuffer, 0, 1024);
	double fps = Timer::GetInstance()->GetFPS();
	sprintf_s(strBuffer, "FPS: %4f", (fps));
	SYSTEM->GetRenderer()->PrintTextWorld( strBuffer, float(SYSTEM->GetWindowWidth())/2 - 800, 
										float(SYSTEM->GetWindowHeight())/2 -10, WHITE, 300, 10);

	
	memset(strBuffer, 0, 1024);
	sprintf_s(strBuffer, "SCORE: %d",sScore*100);
	SYSTEM->GetRenderer()->PrintTextWorld( strBuffer, float(SYSTEM->GetWindowWidth())/2 -400, 
										float(SYSTEM->GetWindowHeight())/2 -10 , WHITE, 500, 10);

	
	if(sScore >= 18)
	{
 		SYSTEM->GetRenderer()->PrintTextWorld( "You Have Won The Game!", -100.f, 0.f, WHITE, 500, 10);
		SYSTEM->GetRenderer()->PrintTextWorld( "Press Esc To Return To Main Menu", -100.f, -20.f, WHITE, 500, 10);
	}

			

	// draw all object instances in the list
	for (unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = sGameObjInstList + i;

		// skip non-active object
		if ((pInst->flag & FLAG_ACTIVE) == 0)
			continue;
		


		
		//draw background
		if(pInst->pObject->type == TYPE_BACKGROUND)
		{
			SYSTEM->GetRenderer()->DrawBackground(pInst->transform);
		}
		// Set the current object instance's transform matrix using "AEGfxSetTransform"
		// Draw the shape used by the current object instance using "AEGfxTriDraw"
		//Draw selected object
		
		//AEGfxSetTransform((AEMtx33 *)&pInst->transform);
		//AEGfxTriDraw(pInst->pObject->pMesh);
		if(pInst->pObject->type == TYPE_ASTEROID)
		{
			SYSTEM->GetRenderer()->DrawAstroid(pInst->transform);
		}
		if(pInst->pObject->type==TYPE_SHIP)
		{
			SYSTEM->GetRenderer()->DrawTexture(pInst->transform);
				
		memset(strBuffer, 0, 1024);
		sprintf_s(strBuffer, "P1",sScore*100);
		SYSTEM->GetRenderer()->PrintTextWorld( strBuffer, pInst->posCurr.x - SHIP_SIZE/3,
												pInst->posCurr.y  + SHIP_SIZE*1.2 , WHITE, 50, 10);

		}
		if(pInst->pObject->type == TYPE_BULLET)
		{
			SYSTEM->GetRenderer()->DrawBulletTexture(pInst->transform);
		}
	}
	
	SYSTEM->GetRenderer()->EndDraw();
}

/******************************************************************************/
/*!
	Free Asteroids
*/
/******************************************************************************/
void SinglePlayerAsteroidsFree(void)
{
	// kill all object instances in the array using "gameObjInstDestroy"
	for(unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = sGameObjInstList + i;

		gameObjInstDestroy(pInst);
	}
}

/******************************************************************************/
/*!
	Unload Asteroids
*/
/******************************************************************************/
void SinglePlayerAsteroidsUnload(void)
{
	
}

/******************************************************************************/
/*!
	Create Objects
*/
/******************************************************************************/
GameObjInst* gameObjInstCreate(unsigned long type, float scale, Vec2* pPos, 
													Vec2* pVel, float dir)
{
	Vec2 zero(0.0f, 0.0f);

	// loop through the object instance list to find a non-used object instance
	for (unsigned long i = 0; i < GAME_OBJ_INST_NUM_MAX; i++)
	{
		GameObjInst* pInst = sGameObjInstList + i;

		// check if current instance is not used
		if (pInst->flag == 0)
		{
			// it is not used => use it to create the new instance
			pInst->pObject	= sGameObjList + type;
			pInst->flag		= FLAG_ACTIVE;
			pInst->scale		= scale;
			pInst->posCurr	= pPos ? *pPos : zero;
			pInst->velCurr	= pVel ? *pVel : zero;
			pInst->dirCurr	= dir;
			
			// return the newly created instance
			return pInst;
		}
	}
	// cannot find empty slot => return 0
	return 0;
}


/******************************************************************************/
/*!
	Destory Objects
*/
/******************************************************************************/
void gameObjInstDestroy(GameObjInst* pInst)
 {
	// if instance is destroyed before, just return
	if (pInst->flag == 0)
		return;

	// zero out the flag
	pInst->flag = 0;
}










